package scenic;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;

import scenic.geom.Affine2;

/**
 * This class is a base class for scene nodes that contain other
 * scene nodes. The child nodes are painted starting from the first
 * child.
 */
public class SceneContainer extends SceneNode implements SceneParent {
	private ArrayList children = new ArrayList();

	/**
	 * Constructs an empty SceneContainer.
	 */
	public SceneContainer() {
	}
	
	/**
	 * Adds a child node to the given index in the child list.
	 * 
	 * @param index the index in the child list.
	 * @param node the child node.
	 */
	public void add(int index, SceneNode node) {
		node.close();
		children.add(index, node);
		node.parent = this;
		node.setVisibility(getVisibility());
		changed(null);
	}

	/**
	 * Adds a child node at the end of the child list.
	 * 
	 * @param node the child node.
	 */
	public void add(SceneNode node) {
		node.close();
		children.add(node);
		node.parent = this;
		node.setVisibility(getVisibility());
		changed(null);
	}

	/**
	 * Removes all child nodes from this container.
	 */
	public void clear() {
		Iterator itr = children.iterator();
		
		while(itr.hasNext())
			((SceneNode)itr.next()).setVisibility(false);		
		children.clear();
		changed(null);
	}

	public void remove(SceneNode node) {
		children.remove(node);
		node.parent = null;
		node.setVisibility(false);
		changed(null);
	}
	
	void draw(DrawContext context, Affine2 transform, Rectangle visibleArea) {
		Iterator itr = children.iterator();
		
		while(itr.hasNext())
			((SceneNode)itr.next()).draw(context, transform, visibleArea);		
	}
	
	void prepareDraw(DrawContext context, Affine2 transform) {
		Iterator itr = children.iterator();
		
		while(itr.hasNext())
			((SceneNode)itr.next()).prepareDraw(context, transform);		
	}
	
	Rectangle getBounds(Affine2 transform) {
		Rectangle result = new Rectangle();
		Iterator itr = children.iterator();
		
		while(itr.hasNext()) {
			SceneNode node = (SceneNode)itr.next();
			Rectangle nodeRect = node.getBounds(transform);
			
			Util.combine(result, nodeRect);
		}

		return result;
	}	
	
	int getDrawType(Affine2 transform) {
		if(children.size() == 1)
			return ((SceneNode)children.get(0)).getDrawType(transform);
		return SceneNode.DRAW_SIMPLE;
	}
	
	void setVisibility(boolean state) {
		Iterator itr = children.iterator();
		
		while(itr.hasNext())
			((SceneNode)itr.next()).setVisibility(state);
		super.setVisibility(state);
	}
	
	public void childChanged(Rectangle area) {
		if(parent != null)
			parent.childChanged(area);
	}
}
